﻿using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Pay.DTO.tenPay;
using Pay.DTO.hfpay;
using Pay.Core;
using Flurl.Http;
using NPOI.SS.UserModel;

namespace Pay.Service.Pay
{
    public class TenPaySign
    {
        public TenPaySign() { }

#if DEBUG
        protected string ten_api_url = "http://pay.tftpay.com";
        protected string ten_privateKey = @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOZfCldx3G/46i4yvHjTrxenAj6uIbaiRu+YDSZaGEiG+BVb6UK+/tGIqFNNzeE9CIf5MeVoH0+kGZOzTVkd/pOZsdNl8VDbrK3o/yf0rPuVy0EemB9nYFuKiCfnqqHiKDfnx1/IkQerXss61fJtiV7C8GrP7/ot/sAp7wqKBdjdAgMBAAECgYBFNoS65QCfu59QJfouKxtN9eVcw6BpaLP7RCmfPi5RjAt5D1YzsYKJnY9FB/k1FMs9Xwc4r2HI4bq1f4dboQFc8S0vKlLfS4B6+PPS3kOjcBgwLa86GBWxW3o6MeL1hiaQc4rKfCHKas31z0lHurO0YZWk7v50BDIs9Ndh0DS9AQJBAPr+bGiClYxBfNfelJ6O/s0KHkPMjsXrU9TKx4mMD8LvAV7gH1WGnojIxCcRzQMnlaUFRkqGMkJ45QmLvUMdzuECQQDq91FcoRQbE9ddH7GaUQkI/KCouJXrExV58ComWpfupg3QCBE3QY5WdQw8URhwtURuvFSXrOG041JqT2apS3V9AkBmFVrEOvBWJkB/kBDEWIZ7oHTkwGsFRoxHDN6RK/0xHIJjMyarY2BRY86b0VqfwNbVUkrffqssa/1Dn6kvhg0hAkAQLEvWY2P95SS6zTatV4yWqMTqOCJhluOwi/5qu2ufyqBCxHti4UlJ3C6mbDKRd3ipYp8z/XtftxHyLVr0pjQFAkAlkXlMdDoVx6fp3QLzFoxge+hgs58SvJHBL/ChhvSTUlecqErA+irIS8WFA4LoAZP8M0uE+wSE/ReSzf/xh7M7";
        protected string ten_publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmXwpXcdxv+OouMrx4068XpwI+riG2okbvmA0mWhhIhvgVW+lCvv7RiKhTTc3hPQiH+THlaB9PpBmTs01ZHf6TmbHTZfFQ26yt6P8n9Kz7lctBHpgfZ2Bbiogn56qh4ig358dfyJEHq17LOtXybYlewvBqz+/6Lf7AKe8KigXY3QIDAQAB";
        protected string ten_mchid = "092100059696790";
#else
        protected string ten_api_url = "http://pay.tftpay.com";
        protected string ten_privateKey = @"MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOZfCldx3G/46i4yvHjTrxenAj6uIbaiRu+YDSZaGEiG+BVb6UK+/tGIqFNNzeE9CIf5MeVoH0+kGZOzTVkd/pOZsdNl8VDbrK3o/yf0rPuVy0EemB9nYFuKiCfnqqHiKDfnx1/IkQerXss61fJtiV7C8GrP7/ot/sAp7wqKBdjdAgMBAAECgYBFNoS65QCfu59QJfouKxtN9eVcw6BpaLP7RCmfPi5RjAt5D1YzsYKJnY9FB/k1FMs9Xwc4r2HI4bq1f4dboQFc8S0vKlLfS4B6+PPS3kOjcBgwLa86GBWxW3o6MeL1hiaQc4rKfCHKas31z0lHurO0YZWk7v50BDIs9Ndh0DS9AQJBAPr+bGiClYxBfNfelJ6O/s0KHkPMjsXrU9TKx4mMD8LvAV7gH1WGnojIxCcRzQMnlaUFRkqGMkJ45QmLvUMdzuECQQDq91FcoRQbE9ddH7GaUQkI/KCouJXrExV58ComWpfupg3QCBE3QY5WdQw8URhwtURuvFSXrOG041JqT2apS3V9AkBmFVrEOvBWJkB/kBDEWIZ7oHTkwGsFRoxHDN6RK/0xHIJjMyarY2BRY86b0VqfwNbVUkrffqssa/1Dn6kvhg0hAkAQLEvWY2P95SS6zTatV4yWqMTqOCJhluOwi/5qu2ufyqBCxHti4UlJ3C6mbDKRd3ipYp8z/XtftxHyLVr0pjQFAkAlkXlMdDoVx6fp3QLzFoxge+hgs58SvJHBL/ChhvSTUlecqErA+irIS8WFA4LoAZP8M0uE+wSE/ReSzf/xh7M7";
        protected string ten_publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmXwpXcdxv+OouMrx4068XpwI+riG2okbvmA0mWhhIhvgVW+lCvv7RiKhTTc3hPQiH+THlaB9PpBmTs01ZHf6TmbHTZfFQ26yt6P8n9Kz7lctBHpgfZ2Bbiogn56qh4ig358dfyJEHq17LOtXybYlewvBqz+/6Lf7AKe8KigXY3QIDAQAB";
        protected string ten_mchid = "092100059696790";
#endif

        public async Task<ten_pay_res> PayGateway<T>(ten_pay_req request, T model, string url) where T : new()
        {
            request.merNo = ten_mchid;
            var log = IocHelper.Get<ILogHelper>("info");
            try
            {
                request.cipher = Cipher(model);
                request.sign = Sign(request);
                var result = await (ten_api_url + url).PostJsonAsync(request).ReceiveString();
                log.Info(result);
                return result.ToObject<ten_pay_res>();
            }
            catch (FlurlHttpException ex)
            {
                log.Error(ex.Message);
                return null;
            }
        }

        private string Cipher<T>(T model) where T : new()
        {
            var log = IocHelper.Get<ILogHelper>("info");
            string result = string.Empty;
            string json = model.ToJson();
            log.Info($"body:{json}");
            var collection = json.ToObject<SortedDictionary<string, string>>();
            foreach (var item in collection)
            {
                if (item.Key == "proType" && item.Value == "0")
                    continue;
                if (!string.IsNullOrEmpty(item.Value))
                {
                    result += "&" + item.Key + "=" + item.Value;
                }
            }
            result = result.Trim('&');
            string sign = RSAFromPkcs.RsaEncryptData(result, ten_publicKey, "utf-8");
            return sign;
        }

        private string Sign(ten_pay_req request)
        {
            var req_head = request.ToJson();
            var headers = req_head.ToObject<SortedDictionary<string, string>>();
            headers.Remove("sign");
            string headStr = string.Empty;
            foreach (var header in headers)
            {
                if (!string.IsNullOrEmpty(header.Value))
                    headStr += string.Format("&{0}={1}", header.Key, header.Value);
            }
            headStr = headStr.Trim('&');
            string sign = RSAFromPkcs.sign(headStr, ten_privateKey, "utf-8");
            return sign;
        }
    }
}
